/*
 * Copyright (c) 2025 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

/**
 * @file    signal_common.h
 * @brief   signal_common
 */
#ifndef SIGNAL_COMMON_H
#define SIGNAL_COMMON_H

#include <tools/list.h>

#define MIN_SIG 1
#define MAX_SIG 64

#define SIG_BLOCK   0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2

#define SIG_NRT_MIN 1
#define SIG_NRT_MAX 31
#define SIG_RT_MIN  32
#define SIG_RT_MAX  64
#define SIG_NO_WAIT (0UL)

#define SIG_OK    0
#define SIG_ERROR (-1)

#define SIG_CLZLL        __builtin_clzll
#define INVALID_PRIORITY (65)
#define SINGLE_TIME      (1)
#define SIG_INDEX(num)   ((num) - 1)

#define IPI_SIGNAL_KILL ((uint8_t)1)

#define SIG_DEFAULT      (0x0UL)  /* default value (no signal flag) */
#define SIG_SYSCALL      (0x01UL) /* signal generated by the first system call */
#define SIG_USER_HANDLE  (0x02UL) /* signal is being handled by a user-defined handler */
#define SIG_RET_KERNEL   (0x04UL) /* signal is returning to the kernel */
#define SIG_IPI_KILL     (0x08UL) /* signal is being handled by an IPI (Inter-Processor Interrupt) handler */
#define SIG_LP_INSTALLED (0x10UL) /* low-priority signal has been installed */
#define SIG_INSTALLED    (0x20UL) /* signal has been installed */
#define SIG_NESTED       (0x40UL) /* signal has been nested */

enum {
    CAP_PTHEAD_KILL = 0,
    CAP_PAUSE_KILL,
    CAP_SIGNAL_INIT,
    CAP_SIGNAL_EXIT,
    CAP_SIGNAL_PROCMASK,
    CAP_SIGNAL_TIME_WAIT,
};
typedef enum {
    SIG_NO = 0,  /* no signal */
    SIG_NEST_HP, /* nested signal with highest priority */
    SIG_REC_HP,  /* installed signal with highest priority */
    SIG_PEND_HP, /* pending signal with highest priority */
} sig_type;

typedef uint64_t sig_set_t;

typedef struct sig_info {
    int32_t  si_signo;
    int32_t  si_errno;
    int32_t  si_code;
    int32_t  si_status;
    void    *si_addr;
    uint32_t si_uid;
    int64_t  si_pid;
} sig_info_t;

typedef struct sig_list {
    list_t waitlist;
} sig_list_t;

typedef struct sig_wait {
    sig_set_t  sig_set;
    sig_info_t sig_info;
    list_t     sig_wait;
} sig_wait_t;

typedef struct sig_cb {
    uint16_t   sig_rec[MAX_SIG];
    context_t  sig_irq_context[MAX_SIG];
    context_t  sig_task_context;
    sig_set_t  sig_rec_map;
    sig_set_t  sig_nest_map;
    sig_set_t  sig_mask_map;
    sig_set_t  sig_pend_map;
    uint64_t   sig_handle_status;
    int32_t    sig_handling_no; /* the highest priority while executing the signal handler */
    uint16_t   task_state;
    sig_wait_t wait_info;
} sig_cb_t;

#endif